package com.learnyou.server.xingzuo.biz.helper;


import com.google.common.collect.Lists;
import com.learnyou.server.xingzuo.common.helper.BinaryDigitHelper;
import com.learnyou.server.xingzuo.common.util.DateUtils;
import com.learnyou.server.xingzuo.dto.resultDTO.StudentScheduleListResultDTO;

import java.time.LocalDate;
import java.time.ZoneOffset;
import java.time.temporal.TemporalAdjusters;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

public class StudentHelper {


    private static final String[][] WEEK_ARRAY = {{"MONDAY", "1"}, {"TUESDAY", "2"}, {"WEDNESDAY", "3"}, {"THURSDAY", "4"}, {"FRIDAY", "5"}, {"SATURDAY", "6"}, {"SUNDAY", "7"}};

    public static String getStatusDesc(StudentScheduleListResultDTO scheduleListResultDTO) {
        if (Objects.nonNull(scheduleListResultDTO)) {
            int left = scheduleListResultDTO.getScheduleLeft();

            if (left > 0) {
                return "学习中";
            } else {
                return "已学完";
            }

//            if (Objects.equals(scheduleListResultDTO.getScheduleLeft(), scheduleListResultDTO.getScheduleTotal())) {
//                return "未开始";
//            } else if (scheduleListResultDTO.getScheduleLeft() == 0) {
//                return "已学完";
//            } else {
//                return "学习中";
//            }
        }
        return null;
    }


    public static Date getMaxLastDate(Integer scheduleWeeks, Integer scheduleMonths, Date startDate, Integer scheduleTotal){
        List<Date> dateList = getStudyDate(scheduleWeeks, scheduleMonths, startDate, scheduleTotal);
        return dateList.get(dateList.size() - 1);
    }


    /**
     * 获取学生课时时间
     * @return
     */
    public static List<Date> getStudyDate(Integer scheduleWeeks, Integer scheduleMonths, Date startDate, Integer scheduleTotal) {
        //星期
        List<Integer> weeks = getValues(scheduleWeeks, "week");
        //月份
        List<Integer> months = getValues(scheduleMonths, "month");
        LocalDate date = DateUtils.fromDate(startDate);
        List<Date> result = Lists.newArrayList();
        LocalDate studyYear = date;
        List<Date> dateList = getStudyDaysByYear(months, weeks, date);
        if(dateList.size() <= scheduleTotal) {
            //一年的课时不够需要补下一年
            result.addAll(dateList.stream().filter(v -> v.compareTo(startDate) >= 0).collect(Collectors.toList()));
            while (result.size() < scheduleTotal){
                //不够就补后面一年的日期
                studyYear = studyYear.plusYears(1);
                List<Date> studyList = getStudyDaysByYear(months, weeks, studyYear);
                int leftDays = scheduleTotal - result.size();
                if(leftDays > studyList.size()){
                    result.addAll(studyList);
                }else {
                    for(int i=0; i < leftDays; i++){
                        result.add(studyList.get(i));
                    }
                }
            }
        }else {
            for(int i=0; i<dateList.size(); i++){
                if(i < scheduleTotal){
                    result.add(dateList.get(i));
                }
            }
        }

        return result;
    }



    public static List<Date> getStudyDaysByYear(List<Integer> months, List<Integer> weeks, LocalDate date){
        List<Date> result = Lists.newArrayList();
        LocalDate firstDay = date.with(TemporalAdjusters.firstDayOfYear()); // 获取当前年的第一天
        LocalDate lastDay = date.with(TemporalAdjusters.lastDayOfYear()); // 获取当前年的最后一天
        result.add(DateUtils.fromLocalDate(firstDay));
        long time = firstDay.atStartOfDay(ZoneOffset.ofHours(8)).toInstant().toEpochMilli();
        long maxTimes = lastDay.atStartOfDay(ZoneOffset.ofHours(8)).toInstant().toEpochMilli();
        while (time < maxTimes){
            LocalDate localDate = firstDay.plusDays(1);
            if(months.contains(localDate.getMonthValue()) && weeks.contains(getDayOfTheWeek(localDate))) {
                result.add(DateUtils.fromLocalDate(localDate));
            }
            firstDay = localDate;
            time = time + 86400000;
        }
        return result;
    }

    /**
     * 根据二进制获取星期几/哪个月份
     */
    private static List<Integer> getValues(Integer scheduleWeeks, String type) {
        if (type.equals("week")) {
            return BinaryDigitHelper.weekNumTo(scheduleWeeks);
        } else {
            return BinaryDigitHelper.toTrueDigitList(scheduleWeeks, 12);
        }

//        Integer value = Integer.parseInt(scheduleWeeks.toString(), 2);
//        List<Integer> result = Lists.newArrayList();
//        int maxValue;
//        if(type.equals("week")) {
//            maxValue = 7;
//        }else {
//            maxValue = 12;
//        }
//        for (int i = 1; i <= scheduleWeeks.toString().length(); i++) {
//            if ((value >> (i - 1) & 1) == 1) {
//                result.add(maxValue - i +1);
//            }
//        }
//        return result.stream().sorted().collect(Collectors.toList());
    }


    /**
     * 获取日期是星期几
     * @param currentDate
     * @return
     */
    public static Integer getDayOfTheWeek(LocalDate currentDate) {
        String k = String.valueOf(currentDate.getDayOfWeek());
        for (int i = 0; i < WEEK_ARRAY.length; i++) {
            if (k.equals(WEEK_ARRAY[i][0])) {
                k = WEEK_ARRAY[i][1];
                break;
            }
        }
        return Integer.parseInt(k);
    }


}
